package com.yunchang.springboot.scheduled.finance;

import com.yunchang.springboot.exception.ErrorLogException;
import com.yunchang.springboot.mapper.base.FinanceShopSkuMapper;
import com.yunchang.springboot.mapper.basic.IDataGetErrorRecordMapper;
import com.yunchang.springboot.mapper.caravan.CaravanBillsDataMapper;
import com.yunchang.springboot.mapper.caravan.CaravanOrderDataMapper;
import com.yunchang.springboot.mapper.caravan.CaravanPurchaseDataMapper;
import com.yunchang.springboot.mapper.caravan.CaravanStorageLogDataMapper;
import com.yunchang.springboot.mapper.finance.*;
import com.yunchang.springboot.mapper.logisticsReconciliation.WlCreateAPlanMapper;
import com.yunchang.springboot.mapper.logisticsReconciliation.WlFreightAllocationMapper;
import com.yunchang.springboot.mapper.shop.ShopMapper;
import com.yunchang.springboot.models.DO.*;
import com.yunchang.springboot.models.DO.finance.*;
import com.yunchang.springboot.models.DO.logisticsReconciliation.WlCreateAPlan;
import com.yunchang.springboot.models.DO.logisticsReconciliation.WlFreightAllocation;
import com.yunchang.springboot.models.DataGetErrorRecord;
import com.yunchang.springboot.models.Shop;
import com.yunchang.springboot.models.base.FinanceShopSku;
import com.yunchang.springboot.scheduled.mwsfinance.FinanceStartScheduled;
import com.yunchang.springboot.service.transactionMethod.FinanceDebitCreditService;
import com.yunchang.springboot.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Slf4j
public class FinanceCaravanDebitCreditSchedule {

    @Resource
    CaravanStorageLogDataMapper storageLogDataMapper;
    @Resource
    CaravanPurchaseDataMapper purchaseDataMapper;
    @Resource
    CaravanBillsDataMapper billsDataMapper;
    @Resource
    CaravanOrderDataMapper orderDataMapper;
    @Resource
    FinanceCaravanDebitCreditRelationMapper financeCaravanDebitCreditRelationMapper;
    @Resource
    FinanceShopSkuMapper shopSkuMapper;
    @Resource
    FinanceSubjectMapper subjectMapper;
    //    @Resource
//    FinanceCaravanProcessingOrderMapper caravanProcessingOrderMapper;
    @Resource
    FinanceCaravanProcessingOrderItemMapper caravanProcessingOrderItemMapper;
    @Resource
    FinanceCaravanDocumentTypeMapper financeCaravanDocumentTypeMapper;
    @Resource
    FinanceCaravanShopNameRelationMapper financeCaravanShopNameRelationMapper;
    @Resource
    FinanceOpeningInventoryMapper financeOpeningInventoryMapper;
    @Resource
    WlFreightAllocationMapper wlFreightAllocationMapper;
    @Resource
    WlCreateAPlanMapper wlCreateAPlanMapper;
    @Resource
    FinanceExchangeRateMapper financeExchangeRateMapper;
    @Resource
    IDataGetErrorRecordMapper iDataGetErrorRecordMapper;
    @Resource
    ShopMapper shopMapper;
    @Resource
    FinanceStartScheduled financeStartScheduled;
    /**
     * 计算出入库流水数据的借贷关系
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void calculateStorageLogData() {
        /*
         * 先获取所有状态为新增和已生成借贷关系但是还没计算值的所有数据（按时间升序），
         * 遍历，拿到每一条的logId去finance_caravan_debit_credit_relation表中找是否还有对应的借贷关系的科目名叫做手动处理的
         * 如果没有，这个时候判断状态是新增还是已生成借贷关系，新增，则根据单据类型生成借贷关系，
         * 这个时候也会碰到生成手工处理的情况，这个时候，可以设置一个标志位置为0，之后都不算值，只生成科目
         * 已生成借贷关系，标志位是1，则直接跳过，是2，则去借贷表中去查找到对应借贷关系，
         * 最后计算值，如果值涉及到库存单价的，根据当前的sku去这个时间之前的数据中找到这个sku的前一个库存单价（能不能直接SQL查询返回数据，试一试）
         * 将数据按格式存储好，存入或更新数据库（这里可以用replace来实现）
         * */
        //先获取所有状态为新增和已生成借贷关系但是还没计算值的所有数据（按时间升序）
        List<CaravanStorageLogData> storageLogDataList = storageLogDataMapper.selectNewAndHandledData();
        //设定一个标志位，为1时可以进行具体数值的计算，为0时只能生成借贷科目名称，无法计算数值
        int flag = 1;
        try {
            for (CaravanStorageLogData storageLogData : storageLogDataList) {
                flag = calculateStorageLogDataWithTransaction(storageLogData, flag);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return;
        }
    }


    /**
     * 计算采购单数据的借贷关系
     */
    @Transactional(rollbackFor = Exception.class)
    public void calculatePurchaseData() {
        /*
         * 先获取所有状态为已付款的数据（按时间升序），
         * 遍历，然后根据每条采购单数据计算出额外费用总值（运费-折扣+税金），
         * 然后获得这条采购单所有明细中的商品数量总和，最后计算出分摊费用=额外费用总值/商品数量总和
         * 算好分摊的运费，开始计算具体不同种类的借贷关系
         * 将数据按格式存储好，存入或更新数据库（这里可以用replace来实现）
         * */
        StringBuffer errorMsg = new StringBuffer();
        //先获取所有“采购中”或以上的且处理状态为新增的采购单数据
        List<CaravanPurchaseData> purchaseDataList = purchaseDataMapper.getPurchasingAndNewData();
        for (CaravanPurchaseData purchaseData : purchaseDataList) {
            try {
                //创建存放借贷关系数据的集合
                String purchaseId = purchaseData.getPurchaseId();
                //获得对应的采购单明细
                List<CaravanPurchaseDataItem> purchaseDataItemList = purchaseDataMapper.getNewItemDataByPurchaseId(purchaseId);
                List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = generatePurchaseDataDebitCreditRelation(purchaseData, purchaseDataItemList);
                //更新采购单处理状态
                purchaseDataMapper.updateHandleStatus(purchaseData);
                //插入或更新借贷关系
                financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
            } catch (Exception e) {
                log.error(e.getMessage());
                errorMsg.append(e.getMessage());
                handleErrorSchedule(purchaseData.getUpdateTime(), "采购单计算财务数据", errorMsg);
                return;
            }
        }
    }

    /**
     * 计算账单数据的借贷关系，包括付款单、收款单、费用单
     */
    @Transactional
    public void calculateBillsData() {
        /*
         * 先获取所有数据，获得数据后先根据账单种类进行一个划分
         * 再根据不同的账单中的不同种类去进行计算
         * */
        log.info("开始生成三种账单的财务数据");
        StringBuffer errorMsg = new StringBuffer();
        //先获得所有状态为已完成和处理状态为新增的的账单数据
        List<CaravanBillsData> billsDataList = billsDataMapper.getCompletedAndNewData();
        for (CaravanBillsData billsData : billsDataList) {
            try {
                //生成借贷关系
                List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = generateBillsDataDebitCreditRelation(billsData);
                //更新账单的处理状态
                billsDataMapper.updateHandleStatus(billsData);
                //插入或更新借贷关系
                financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
            } catch (Exception e) {
                log.error(e.getMessage());
                errorMsg.append(e.getMessage());
                handleErrorSchedule(billsData.getPayTime(), "收付款单计算财务数据", errorMsg);
                return;
            }
        }
        log.info("生成三种账单的财务数据结束");
    }

    /**
     * 计算分摊运费的借贷关系和数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void calculateAllocatedFreight() {
        /*
         * 先获取处理状态为新增且在借贷关系中已经有FBA出库类型的借贷关系对应的shipmentid和sku结合的分摊运费数据，
         * 删除对应的shipment_log_number且status是未结算状态的所有借贷关系，重新计算新的借贷关系
         * 单号存亚马逊提供的shippmentId，关联单号放自己系统生成的发货批次号
         * */

        //从分摊运费表中获得处理状态为新增的数据
        List<WlFreightAllocation> wlFreightAllocationList = wlFreightAllocationMapper.getNewDataByhandleStatus();
        OUT:
        for (WlFreightAllocation wlFreightAllocation : wlFreightAllocationList) {
            List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
            StringBuffer errorMsg = new StringBuffer();
            String shippNo = wlFreightAllocation.getShippNo();
            String platformSku = wlFreightAllocation.getPlatformSku();
            try {
                //根据这个shippno去创建计划表中查找对应的店铺和国家
                WlCreateAPlan planData = wlCreateAPlanMapper.getShopDataByShipmentId(shippNo);
                String sellerId = planData.getSellerId();
                String area = planData.getCountryName();
                String shipmentIdReplace = planData.getShipmentIdReplace();
                //删除和这个shipmentId有关的借贷关系（因为之后还要根据这个shipmentId再计算出借贷数据）
                financeCaravanDebitCreditRelationMapper.delDataByShipmentIdAndPlatformSku(shippNo, platformSku);
                //需要两部分的数据，一部分是分摊的运费，一部分是FBA发货出库时的单价
                //分摊的运费
                BigDecimal allocatedFreight = wlFreightAllocation.getAllocatedFreight();
                Integer delieverQuantity = wlFreightAllocation.getDelieverQuantity();
                //FBA发货出库时的单价
                //把之前存在使用过的那些shipmentId都存储起来
                List<String> shipmentIdList = new ArrayList<>();
                //如果shipmentIdReplace有值
                if (shipmentIdReplace != null && "".equals(shipmentIdReplace)) {
                    //先按逗号切割shipmentIdReplace
                    String[] shipmentIds = shipmentIdReplace.split(",");
                    shipmentIdList = Arrays.asList(shipmentIds);
                }
                shipmentIdList.add(shippNo);
                FinanceCaravanDebitCreditRelation fbaDeliveryDebitCreditRelation = null;
                //设置标记，记录本条分摊运费的数据是否可以匹配到对应的fba出库记录并计算完财务数据
                boolean flag = false;
                IN:
                for (int i = 0; i < shipmentIdList.size(); i++) {
                    String shipmentId = shipmentIdList.get(i);
                    fbaDeliveryDebitCreditRelation = financeCaravanDebitCreditRelationMapper.getDataByRelatedRecordNoSkuDocumentTypeAndLoanType(shipmentId, platformSku, 1, 1, sellerId, area);
//                    if (fbaDeliveryDebitCreditRelation == null) {
//                        continue IN;
//                    }
                    if (fbaDeliveryDebitCreditRelation == null && shipmentIdList.size() == 1) {
                        log.info("没有对应的FBA发货出库记录，请检查数据是否正确");
                        errorMsg.append("shipmentId:" + shippNo + ",platformSku:" + platformSku + ",没有对应的FBA发货出库记录");
                        handleErrorSchedule(wlFreightAllocation.getDataTime(), "分摊运费表计算财务数据", errorMsg);
                        continue OUT;
                    }
                    if (fbaDeliveryDebitCreditRelation == null) {
                        log.info("找不到任何的FBA发货出库记录去匹配，请检查数据是否正确");
                        errorMsg.append("shipmentId:" + shippNo + ",platformSku:" + platformSku + ",找不到任何的FBA发货出库记录去匹配");
                        handleErrorSchedule(wlFreightAllocation.getDataTime(), "分摊运费表计算财务数据", errorMsg);
                        continue IN;
                    }
                    if (fbaDeliveryDebitCreditRelation.getOriginalAmount() == null) {
                        log.info("对应的FBA发货出库还没有计算完金额");
                        errorMsg.append("shipmentId:" + shippNo + ",platformSku:" + platformSku + ",对应的FBA发货出库还没有计算完金额");
//                        handleErrorSchedule(wlFreightAllocation.getDataTime(), "分摊运费表计算财务数据", errorMsg);
                        continue IN;
                    }
                    BigDecimal debitCreditRelationAmount = fbaDeliveryDebitCreditRelation.getOriginalAmount();
                    Integer debitCreditRelationSkuNum = fbaDeliveryDebitCreditRelation.getSkuNum();
                    BigDecimal costUnitPrice = debitCreditRelationAmount.divide(BigDecimal.valueOf(debitCreditRelationSkuNum), 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal estimationMaterialsInTransit = costUnitPrice.multiply(BigDecimal.valueOf(delieverQuantity));
                    //在途物资-子科目名的值
                    BigDecimal materialsInTransit = allocatedFreight.add(estimationMaterialsInTransit);
                    //生成对应的借贷关系
                    String cSubjectName = fbaDeliveryDebitCreditRelation.getCSubjectName();
                    Integer documentType = 28;
                    switch (cSubjectName) {
                        case "暂估美西海外仓":
                            FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140203, 1, materialsInTransit, sellerId, area, shipmentIdReplace);
                            FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 660114, 2, allocatedFreight, sellerId, area, shipmentIdReplace);
                            FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140207, 2, estimationMaterialsInTransit, sellerId, area, shipmentIdReplace);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                            break;
                        case "暂估美东海外仓":
                            debitCreditRelation1 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140204, 1, materialsInTransit, sellerId, area, shipmentIdReplace);
                            debitCreditRelation2 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 660114, 2, allocatedFreight, sellerId, area, shipmentIdReplace);
                            debitCreditRelation3 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140208, 2, estimationMaterialsInTransit, sellerId, area, shipmentIdReplace);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                            break;
                        case "暂估FBA":
                            debitCreditRelation1 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140205, 1, materialsInTransit, sellerId, area, shipmentIdReplace);
                            debitCreditRelation2 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 660114, 2, allocatedFreight, sellerId, area, shipmentIdReplace);
                            debitCreditRelation3 = loadAllocatedFreightDebitCreditRelation(wlFreightAllocation, documentType, 140209, 2, estimationMaterialsInTransit, sellerId, area, shipmentIdReplace);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                            break;
                    }
                    flag = true;
                }
                if (flag) {
                    wlFreightAllocation.setHandleStatus(2);
                    //更新查到的这些分摊运费数据，将处理状态改为2
                    wlFreightAllocationMapper.updateHandleStatus(wlFreightAllocation);
                }
                //将借贷关系存入数据库中
                if (financeCaravanDebitCreditRelationList.size() != 0) {
                    financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                errorMsg.append("shipmentId:" + shippNo + ",platformSku:" + platformSku + "的分摊运费数据没有计算成功，详情：");
                errorMsg.append(e.getMessage());
                handleErrorSchedule(wlFreightAllocation.getDataTime(), "分摊运费表计算财务数据", errorMsg);
                return;
            }
        }
        log.info("生成分摊运费的财务数据成功");
    }

    /**
     * 亚马逊财务数据和马帮财务数据联动方法,在马帮部分的财务数据结束后，调用这个方法
     */
    @Scheduled(cron = "00 46 17 07 08 ?")
    @Transactional(rollbackFor = Exception.class )
    public void startMwsData() throws ParseException, CloneNotSupportedException {
        /*
         * 去借贷关系表中查is_inventory_details字段为2的数据，日期从这些数据中最大的那天加一天开始，
         * 再去借贷关系表中查已经没有手动处理科目且金额都已经计算完成的日期，时间区间到这一天结束
         * 调用mws部分的财务数据计算逻辑，把时间参数传入
         * */
        String latestDateWithIsInventoryDetails = financeCaravanDebitCreditRelationMapper.getLatestDateFromFInventoryDetails();
        String latestDateWithNoManualProcess = financeCaravanDebitCreditRelationMapper.getLatestDateWithNoManualProcess();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate startDate = LocalDate.parse(latestDateWithIsInventoryDetails, df);
        LocalDate endDate = LocalDate.parse(latestDateWithNoManualProcess, df);
        startDate = startDate.minusDays(-1);
        long day = endDate.toEpochDay() - startDate.toEpochDay();
        log.info("开始计算亚马逊财务数据");
        StringBuffer errorMsg = new StringBuffer();
        String dateString = "";
        try {
            for (int i = 0; i <= day; i++) {
                dateString = df.format(startDate);
                //调用亚马逊部分的财务数据计算方法
                financeStartScheduled.mwsFinanceStartByDate(dateString);
                //开始时间后延一天
                startDate = startDate.minusDays(-1);
            }
        } catch (RuntimeException e) {
            log.warn("亚马逊财务数据计算失败，详情:" + e);
            errorMsg.append("亚马逊财务数据计算失败，详情:").append(e);
            handleErrorSchedule(dateString, "", errorMsg);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }


    /**
     * 生成采购单数据的借贷关系科目和值
     */
    private List<FinanceCaravanDebitCreditRelation> generatePurchaseDataDebitCreditRelation(CaravanPurchaseData purchaseData, List<CaravanPurchaseDataItem> purchaseDataItemList) {
        List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
        HashMap<Integer, Integer> subjectMap = new HashMap<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String groupId = purchaseData.getGroupId();
        String updateTime = purchaseData.getUpdateTime();
        String targetWarehouseName = purchaseData.getTargetWarehouseName();
//        Integer flag = Integer.parseInt(purchaseData.getFlag());
        //获得运费、折扣、税金
        BigDecimal freightSum = purchaseData.getFreightSum();
        BigDecimal discountAmount = purchaseData.getDiscountAmount();
        BigDecimal taxAmount = purchaseData.getTaxAmount();
        //需要先把运费、税金、折扣分摊
        BigDecimal additionalCosts = freightSum.add(taxAmount).subtract(discountAmount);
        BigDecimal apportionedExpenses = BigDecimal.ZERO;
        for (CaravanPurchaseDataItem purchaseDataItem : purchaseDataItemList) {
            Integer purchaseNum = purchaseDataItem.getPurchaseNum();
            Integer quantitySum = 0;
            quantitySum += purchaseNum;
            apportionedExpenses = additionalCosts.divide(BigDecimal.valueOf(quantitySum), 4, BigDecimal.ROUND_HALF_UP);
        }
        //判断该采购单之前是否已经有借贷关系生成了
        List<FinanceCaravanDebitCreditRelation> preDebitCreditRelationList = financeCaravanDebitCreditRelationMapper.getDataByGroupIdAndTime(groupId, updateTime);

        //根据具体种类进行计算
        FinanceCaravanDocumentType financeCaravanDocumentType = financeCaravanDocumentTypeMapper.getInfoByRecordTypeAndDocumentName(4, targetWarehouseName);
        int documentType = financeCaravanDocumentType.getDocumentType();
        //遍历采购明细
        for (CaravanPurchaseDataItem purchaseDataItem : purchaseDataItemList) {
            try {
                Integer purchaseNum = purchaseDataItem.getPurchaseNum();
                BigDecimal sellPrice = purchaseDataItem.getSellPrice();
                //不加分摊费用的总金额值,主要用在采购的种类
                BigDecimal amount = sellPrice.multiply(BigDecimal.valueOf(purchaseNum));
                //加了分摊费用的总金额值，主要用在其他的种类上
                BigDecimal totalAmount = (sellPrice.add(apportionedExpenses)).multiply(BigDecimal.valueOf(purchaseNum));
                switch (documentType) {
                    case 17:
                        //140206--在途物资-采购
                        //220211--应付账款-采购暂估
                        //660117--销售费用-采购运费	220212-应付账款-采购
                        //660118--销售费用-采购税金	220212-应付账款-采购
                        //660119--销售费用-采购折扣	220212-应付账款-采购
                        //先直接生成运费、税金、折扣的借贷关系
                        FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 660117, 1, freightSum);
                        FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 220212, 2, freightSum);
                        FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 660118, 1, taxAmount);
                        FinanceCaravanDebitCreditRelation debitCreditRelation4 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 220212, 2, taxAmount);
                        FinanceCaravanDebitCreditRelation debitCreditRelation5 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 660119, 1, discountAmount);
                        FinanceCaravanDebitCreditRelation debitCreditRelation6 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, 17, 220212, 2, discountAmount);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation4);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation5);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation6);
                        subjectMap.put(1, 140206);
                        subjectMap.put(2, 220211);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, amount));
                        break;
                    case 18:
                        //660101--销售费用-运费
                        //220202--应付账款-运费
                        subjectMap.put(1, 660101);
                        subjectMap.put(2, 220202);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                    case 19:
                        //6602  --管理费用
                        //220213--应付账款-办公
                        subjectMap.put(1, 6602);
                        subjectMap.put(2, 220213);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                    case 20:
                        //222101--应交税费-进项税
                        //220208--应付账款-进项税
                        subjectMap.put(1, 222101);
                        subjectMap.put(2, 220208);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                    case 21:
                        //1601  --固定资产
                        //220209--应付账款-固定资产
                        subjectMap.put(1, 1601);
                        subjectMap.put(2, 220209);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                    case 22:
                        //6602  --管理费用
                        //220210--应付账款-管理费用
                        subjectMap.put(1, 6602);
                        subjectMap.put(2, 220210);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                    case 23:
                        //220205--应付账款-无形资产
                        //1701  --无形资产
                        subjectMap.put(1, 220205);
                        subjectMap.put(2, 1701);
                        financeCaravanDebitCreditRelationList.addAll(generatePurchaseDataDebitCreditRelationByStatus(purchaseData, purchaseDataItem, preDebitCreditRelationList, documentType, subjectMap, totalAmount));
                        break;
                }
                //purchaseDataItem.setHandleStatus(2);
            } catch (Exception e) {
                log.error("purchaseId:" + purchaseDataItem.getPurchaseId() + ",documentType:" + documentType + "的科目金额生成出现错误，详情：" + e);
                throw new ErrorLogException("purchaseId:" + purchaseDataItem.getPurchaseId() + ",documentType:" + documentType + "的科目金额生成出现错误，详情：" + e);
            }
        }
        purchaseData.setHandleStatus(2);
        return financeCaravanDebitCreditRelationList;
    }

    /**
     * 不同状态下的借贷关系生成逻辑
     */
    private List<FinanceCaravanDebitCreditRelation> generatePurchaseDataDebitCreditRelationByStatus(CaravanPurchaseData purchaseData, CaravanPurchaseDataItem purchaseDataItem, List<FinanceCaravanDebitCreditRelation> preDebitCreditRelationList, int documentType, HashMap<Integer, Integer> subjectMap, BigDecimal amount) {
        List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
        Integer flag = Integer.parseInt(purchaseData.getFlag());
        String groupId = purchaseData.getGroupId();
        String updateTime = purchaseData.getUpdateTime();
        BigDecimal preAmount = BigDecimal.ZERO;
        Integer preSkuNum = null;
        if (preDebitCreditRelationList.size() != 0 && preDebitCreditRelationList != null) {
            preAmount = preDebitCreditRelationList.get(0).getAmount();
            preSkuNum = preDebitCreditRelationList.get(0).getSkuNum();
        }
        Integer purchaseNum = purchaseDataItem.getPurchaseNum();
        BigDecimal sellPrice = purchaseDataItem.getSellPrice();
        if (flag >= 4 && flag <= 9) {
            if (preDebitCreditRelationList.size() == 0) {
                FinanceCaravanDebitCreditRelation debitCreditRelation7 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(1), 1, amount);
                FinanceCaravanDebitCreditRelation debitCreditRelation8 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(2), 2, amount);
                financeCaravanDebitCreditRelationList.add(debitCreditRelation7);
                financeCaravanDebitCreditRelationList.add(debitCreditRelation8);
            } else {
                //判断单价和数量是否有变化
                //有变化
                if (!(preSkuNum.compareTo(purchaseNum) == 0 && preAmount.compareTo(amount) == 0)) {
                    //去查关联单号是这个采购单的出入库借贷关系，如果有，就更新这个出入库的借贷关系
                    List<FinanceCaravanDebitCreditRelation> storageLogDataDebitCreditRelationList = financeCaravanDebitCreditRelationMapper.getStorageLogDataRelationByGroupIdAndTime(groupId, updateTime);
                    if (storageLogDataDebitCreditRelationList.size() != 0 && BigDecimal.valueOf(preSkuNum).multiply(sellPrice).compareTo(preAmount) != 0) {
                        //更新出入库的借贷关系，主要就是改了单价，所以要把金额再算一遍
                        for (FinanceCaravanDebitCreditRelation debitCreditRelation : preDebitCreditRelationList) {
                            debitCreditRelation.setAmount(BigDecimal.valueOf(preSkuNum).multiply(sellPrice));
                            debitCreditRelation.setOriginalAmount(BigDecimal.valueOf(preSkuNum).multiply(sellPrice));
                        }
                        financeCaravanDebitCreditRelationList.addAll(storageLogDataDebitCreditRelationList);
                    }
                    //不管有没有出入库的借贷关系，都要做这步操作，更新之前生成的采购单的财务数据
                    for (FinanceCaravanDebitCreditRelation debitCreditRelation : preDebitCreditRelationList) {
                        debitCreditRelation.setSkuNum(purchaseNum);
                        debitCreditRelation.setAmount(amount);
                        debitCreditRelation.setOriginalAmount(amount);
                        debitCreditRelation.setDataTime(updateTime);
                    }
                    financeCaravanDebitCreditRelationList.addAll(preDebitCreditRelationList);
                }
            }
        }
        if (flag == 10) {
            if (preDebitCreditRelationList.size() == 0) {
                //直接生成
                FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(1), 1, amount);
                FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(2), 2, amount);
                financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
            } else {
                //数量发生变化
                if (purchaseNum != preSkuNum) {
                    FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(1), 1, BigDecimal.ZERO.subtract(preAmount));
                    FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(2), 2, BigDecimal.ZERO.subtract(preAmount));
                    FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(1), 1, amount);
                    FinanceCaravanDebitCreditRelation debitCreditRelation4 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, subjectMap.get(2), 2, amount);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation4);
                }
                //单价发生变化
                if (purchaseNum == preSkuNum && amount.compareTo(preAmount) != 0) {
                    FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, 1000, 1, amount);
                    FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadPurchaseDataDebitCreditRelation(purchaseData, purchaseDataItem, documentType, 1000, 2, amount);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                }
            }
        }
        if (flag == 12) {
            if (preDebitCreditRelationList.size() != 0) {
                for (FinanceCaravanDebitCreditRelation debitCreditRelation : preDebitCreditRelationList) {
                    financeCaravanDebitCreditRelationMapper.delete(debitCreditRelation);
                }
            }
        }
        return financeCaravanDebitCreditRelationList;
    }

    /**
     * 通用的生成采购单数据的借贷关系的方法
     */
    private FinanceCaravanDebitCreditRelation loadPurchaseDataDebitCreditRelation(CaravanPurchaseData purchaseData, CaravanPurchaseDataItem purchaseDataItem, int documentType, int subjectId, int loanType, BigDecimal originalAmount) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowTime = LocalDateTime.now().format(df);
        String groupId = purchaseData.getGroupId();
        String sku = purchaseDataItem.getStockSku();
        Integer skuNum = purchaseDataItem.getEnterWarehouseNum();
        String wareHouse = purchaseData.getTargetWarehouseName();
        String providerName = purchaseData.getProviderName();
        String updateTime = purchaseData.getUpdateTime();
        String createTime = purchaseData.getCreateTime();
//        //目前暂时使用创建时间去生成之前你的数据，之后还是要改回更新时间
//        LocalDateTime updateDateTime = LocalDateTime.parse(updateTime, df);
//        int year = updateDateTime.getYear();
//        int month = updateDateTime.getMonthValue();
        LocalDateTime createDateTime = LocalDateTime.parse(createTime, df);
        int year = createDateTime.getYear();
        int month = createDateTime.getMonthValue();
        FinanceCaravanDebitCreditRelation debitCreditRelation = new FinanceCaravanDebitCreditRelation();
        debitCreditRelation.setRecordNo(groupId);
        debitCreditRelation.setRecordType(4);
        //获得当前这条数据的sku对应的店铺信息
        FinanceShopSku financeShopSku = shopSkuMapper.getInfoBySku(sku);
        if (financeShopSku != null) {
            debitCreditRelation.setSellerId(financeShopSku.getSellerId());
            debitCreditRelation.setShopName(financeShopSku.getShopName());
            debitCreditRelation.setArea(financeShopSku.getArea());
        } else {
            debitCreditRelation.setSellerId("");
            debitCreditRelation.setShopName("");
            debitCreditRelation.setArea("");
        }
        debitCreditRelation.setSku(sku);
        debitCreditRelation.setSkuNum(skuNum);
        debitCreditRelation.setSuppiler(providerName);
        debitCreditRelation.setWarehouse(wareHouse);
        debitCreditRelation.setDocumentType(documentType);
        debitCreditRelation.setLoanType(loanType);
        //这里需要根据subjectID查找到子父科目名
        FinanceSubject financeSubject = subjectMapper.getInfoBysubjectId(subjectId);
        debitCreditRelation.setSubjectId(subjectId);
        debitCreditRelation.setPSubjectName(financeSubject.getPSubject());
        debitCreditRelation.setCSubjectName(financeSubject.getSubject());
        debitCreditRelation.setCurrency("CNY");
        debitCreditRelation.setOriginalAmount(originalAmount);
        BigDecimal exchangeRate = financeExchangeRateMapper.getExchangeRateByCurrencyAndDate("CNY", year, month);
        debitCreditRelation.setAmount(originalAmount.multiply(exchangeRate));
        //debitCreditRelation.setDataTime(updateTime);
        //之前的数据暂时使用创建时间去确定
        debitCreditRelation.setDataTime(createTime);
        debitCreditRelation.setRelatedPerson(purchaseData.getCreateOperName());
        debitCreditRelation.setCreator("系统生成");
        debitCreditRelation.setCreateTime(nowTime);
        debitCreditRelation.setStatus(1);
        debitCreditRelation.setIsInventoryDetails(1);
        return debitCreditRelation;
    }

    /**
     * 生成账单数据的借贷关系科目和值
     */
    private List<FinanceCaravanDebitCreditRelation> generateBillsDataDebitCreditRelation(CaravanBillsData billsData) {
        List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
        //先判断这个账单属于哪种，1收款单  2 付款单  3费用单
        String orderType = billsData.getOrderType();
        String paymentTerm = billsData.getPaymentTerm();
        FinanceCaravanDocumentType financeCaravanDocumentType = financeCaravanDocumentTypeMapper.getInfoByRecordTypeAndDocumentName(Integer.parseInt(orderType), paymentTerm);
        int documentType = financeCaravanDocumentType.getDocumentType();
        try {
            switch (orderType) {
                case "1":
                    //该种类下所有的小种类都是同一种计算方式
                    FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadBillsDataDebitCreditRelation(billsData, documentType, 100202, 1);
                    FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadBillsDataDebitCreditRelation(billsData, documentType, 1000, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    //设置处理状态为1
                    billsData.setHandleStatus(1);
                    break;
                case "2":
                    //其中有部分采购相关的小种类的数据需要有不同的逻辑生成借贷关系
                    if (documentType == 25) {
                        String orderNum = billsData.getOrderNum();
                        String updateTime = billsData.getUpdateTime();
                        BigDecimal amountSum = financeCaravanDebitCreditRelationMapper.getAmountByRecordTypeRelatedRecordSkuLoanTypeSubjectId(2, orderNum, "", 1, 112301, updateTime);
                        debitCreditRelation1 = loadBillsDataDebitCreditRelation(billsData, documentType, 112301, 1);
                        debitCreditRelation2 = loadBillsDataDebitCreditRelation(billsData, documentType, 220212, 1);
                        FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadBillsDataDebitCreditRelation(billsData, documentType, 100202, 2);
                        //这里需要再额外计算一遍金额
                        debitCreditRelation1.setAmount(billsData.getAmount().subtract(amountSum));
                        debitCreditRelation1.setOriginalAmount(billsData.getAmount().subtract(amountSum));
                        debitCreditRelation2.setAmount(amountSum);
                        debitCreditRelation2.setOriginalAmount(amountSum);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                        //设置处理状态为2
                        billsData.setHandleStatus(2);
                    }
                    if (documentType == 26) {
                        debitCreditRelation1 = loadBillsDataDebitCreditRelation(billsData, documentType, 1000, 1);
                        debitCreditRelation2 = loadBillsDataDebitCreditRelation(billsData, documentType, 1000, 2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        //设置处理状态为1
                        billsData.setHandleStatus(1);
                    }
                    break;
                case "3":
                    //该种类下所有的小种类都是同一种计算方式
                    debitCreditRelation1 = loadBillsDataDebitCreditRelation(billsData, documentType, 1000, 1);
                    debitCreditRelation2 = loadBillsDataDebitCreditRelation(billsData, documentType, 100202, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    //设置处理状态为1
                    billsData.setHandleStatus(1);
                    break;
            }
        } catch (Exception e) {
            log.warn("orderNum:" + billsData.getOrderNum() + ",documentType:" + documentType + "的科目生成出现错误，详情：" + e);
            throw new ErrorLogException("logId:" + billsData.getOrderNum() + ",documentType:" + documentType + "的科目生成出现错误，详情：" + e);
        }
        return financeCaravanDebitCreditRelationList;
    }

    /**
     * 通用的生成账单数据的借贷关系的方法
     */
    private FinanceCaravanDebitCreditRelation loadBillsDataDebitCreditRelation(CaravanBillsData billsData, int documentType, int subjectId, int loanType) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowTime = LocalDateTime.now().format(df);
        String orderNum = billsData.getOrderNum();
        BigDecimal originalAmount = billsData.getAmount();
        String currency = billsData.getCurrency();
        String payTime = billsData.getPayTime();
        LocalDateTime payDateTime = LocalDateTime.parse(payTime, df);
        int year = payDateTime.getYear();
        int month = payDateTime.getMonthValue();
        FinanceCaravanDebitCreditRelation debitCreditRelation = new FinanceCaravanDebitCreditRelation();
        debitCreditRelation.setRecordNo(orderNum);
        debitCreditRelation.setRecordType(Integer.parseInt(billsData.getOrderType()));
        debitCreditRelation.setSellerId("");
        debitCreditRelation.setShopName("");
        debitCreditRelation.setArea("");
        debitCreditRelation.setBankAccount(billsData.getAccountId());
        debitCreditRelation.setSuppiler(billsData.getPaymentSupplierName());
        debitCreditRelation.setDocumentType(documentType);
        debitCreditRelation.setLoanType(loanType);
        //这里需要根据subjectID查找到子父科目名
        FinanceSubject financeSubject = subjectMapper.getInfoBysubjectId(subjectId);
        debitCreditRelation.setSubjectId(subjectId);
        debitCreditRelation.setPSubjectName(financeSubject.getPSubject());
        debitCreditRelation.setCSubjectName(financeSubject.getSubject());
        if ("RMB".equals(currency)) {
            currency = "CNY";
        }
        debitCreditRelation.setCurrency(currency);
        debitCreditRelation.setOriginalAmount(originalAmount);
        BigDecimal exchangeRate = financeExchangeRateMapper.getExchangeRateByCurrencyAndDate(currency, year, month);
        debitCreditRelation.setAmount(originalAmount.multiply(exchangeRate));
        debitCreditRelation.setDataTime(payTime);
        debitCreditRelation.setRelatedPerson(billsData.getAuditor());
        debitCreditRelation.setCreator("系统生成");
        debitCreditRelation.setCreateTime(nowTime);
        debitCreditRelation.setStatus(1);
        debitCreditRelation.setIsInventoryDetails(1);
        return debitCreditRelation;
    }

    /**
     * 生成分摊运费的借贷关系的方法
     */
    private FinanceCaravanDebitCreditRelation loadAllocatedFreightDebitCreditRelation(WlFreightAllocation wlFreightAllocation, int documentType, int subjectId, int loanType, BigDecimal amount, String sellerId, String area, String shipmentIdReplace) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowTime = LocalDateTime.now().format(df);
        String shippNo = wlFreightAllocation.getShippNo();
//        String shipmentLotNumber = wlFreightAllocation.getShipmentLotNumber();
        FinanceCaravanDebitCreditRelation debitCreditRelation = new FinanceCaravanDebitCreditRelation();
        debitCreditRelation.setRecordNo(shippNo);
        debitCreditRelation.setRecordType(6);
        debitCreditRelation.setSellerId(sellerId);
        //获得对应店铺名
        Shop oneInfoBySellerId = shopMapper.getOneInfoBySellerId(sellerId);
        debitCreditRelation.setShopName(oneInfoBySellerId.getShopName());
        debitCreditRelation.setArea(area);
        debitCreditRelation.setSku(wlFreightAllocation.getPlatformSku());
        debitCreditRelation.setSkuNum(wlFreightAllocation.getDelieverQuantity());
        debitCreditRelation.setDocumentType(documentType);
        debitCreditRelation.setLoanType(loanType);
        //这里需要根据subjectID查找到子父科目名
        FinanceSubject financeSubject = subjectMapper.getInfoBysubjectId(subjectId);
        debitCreditRelation.setSubjectId(subjectId);
        debitCreditRelation.setPSubjectName(financeSubject.getPSubject());
        debitCreditRelation.setCSubjectName(financeSubject.getSubject());
        debitCreditRelation.setRelatedRecordNo(shipmentIdReplace);
        debitCreditRelation.setCurrency("CNY");
        debitCreditRelation.setOriginalAmount(amount);
        debitCreditRelation.setAmount(amount);
        debitCreditRelation.setDataTime(wlFreightAllocation.getDataTime());
        debitCreditRelation.setCreator("系统生成");
        debitCreditRelation.setCreateTime(nowTime);
        debitCreditRelation.setStatus(1);
        debitCreditRelation.setIsInventoryDetails(1);
        return debitCreditRelation;
    }


    /**
     * 马帮出入库数据生成借贷关系的事务方法
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public int calculateStorageLogDataWithTransaction(CaravanStorageLogData storageLogData, int flag) {
        StringBuffer errorMsg = new StringBuffer();
        try {
            //创建存放借贷关系数据的集合
            List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
            String logId = storageLogData.getLogId();
            int handleStatus = storageLogData.getHandleStatus();
            //如果是新增的数据
            if (handleStatus == 0) {
                //根据具体的单据类型，生成对应借贷关系
                //这边只是生成科目
                log.info("开始生成借贷关系");
                financeCaravanDebitCreditRelationList = generateStorageLogDataDebitCreditSubject(storageLogData);
                storageLogData.setHandleStatus(1);
            } else {
                log.info("开始获取原有的借贷关系");
                financeCaravanDebitCreditRelationList = financeCaravanDebitCreditRelationMapper.getDataByRecordIdAndRecordType(logId, 5);
            }
            //判断生成的借贷关系中是否有手动处理的科目
            ISMANUAL:
            for (FinanceCaravanDebitCreditRelation debitCreditRelation : financeCaravanDebitCreditRelationList) {
                if (debitCreditRelation.getSubjectId().compareTo(1000) == 0) {
                    flag = 0;
                    break ISMANUAL;
                }
            }
            //如果flag是1，表示当前已经没有手动处理的科目，可以开始计算具体的数值
            if (flag == 1) {
                //先计算每条数据的库存单价和剩余库存,然后根据每条数据的具体单据类型计算借贷关系的数值
                log.info("开始生成借贷关系金额");
                generateStorageLogDataDebitCreditRelationValue(storageLogData, financeCaravanDebitCreditRelationList);
                storageLogData.setHandleStatus(2);
            }
            //更新出入库流水数据的状态和剩余库存、库存单价
            log.info("更新出入库数据的状态和剩余库存、库存单价");
            storageLogDataMapper.updateHandleStatusAndAmount(storageLogData);
            //log.info("更新出入库数据的状态和剩余库存、库存单价成功");
            //将生成的借贷关系存入数据库中
            if (financeCaravanDebitCreditRelationList.size() != 0) {
                if (handleStatus == 0) {
                    log.info("新增财务数据");
                    financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
                    //log.info("新增财务数据成功");
                } else {
                    log.info("更新财务数据");
                    financeCaravanDebitCreditRelationMapper.replaceDataList(financeCaravanDebitCreditRelationList);
                    //log.info("更新财务数据成功");
                }
            } else {
                log.warn("单号为:" + storageLogData.getLogId() + "的出入库流水的财务数据为0条");
            }
        } catch (ErrorLogException e) {
            log.error("当前出入库数据生成财务数据出现错误");
            handleErrorSchedule(storageLogData.getTimeCreate(), "出入库流水计算财务数据", errorMsg.append(e.getMessage()));
            throw e;
        } catch (Exception e1) {
            e1.printStackTrace();
            log.error("单号为:" + storageLogData.getLogId() + "的出入库流水生成财务数据错误");
            throw e1;
        }
        return flag;
    }

    /**
     * 根据具体单据类型生成借贷关系的科目名称
     */
    private List<FinanceCaravanDebitCreditRelation> generateStorageLogDataDebitCreditSubject(CaravanStorageLogData storageLogData) {
        StringBuffer errorMsg = new StringBuffer();
        List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = new ArrayList<>();
        String documentNum = storageLogData.getDocumentNum();
        String sku = storageLogData.getStockSku();
        String documentName = storageLogData.getDocumentType();
        String warehouse = storageLogData.getWearhouseName();
        String timeCreate = storageLogData.getTimeCreate();
        if ("手工出库".equals(documentName) || "手工入库".equals(documentName)) {
            int quantity = storageLogData.getQuantity();
            if (quantity >= 0) {
                documentName = "手工入库";
            } else {
                documentName = "手工出库";
            }
        }
        FinanceCaravanDocumentType financeCaravanDocumentType = financeCaravanDocumentTypeMapper.getInfoByRecordTypeAndDocumentName(5, documentName);
        int documentType = financeCaravanDocumentType.getDocumentType();
        try {
            switch (documentType) {
                case 14:  //"采购入库"
                    //把quantity取绝对值
                    //这里需要去查到关联的采购单数据，看看是不是实际入库的比采购单的多，如果是，则再加一组借贷关系
                    //如果是采购单，需要把documentNum截取后五位，才是对应的purchaseId
                    String purchaseId = documentNum.substring(documentNum.length() - 5);
                    if (sku.contains("delete")) {
                        sku = sku.substring(0, sku.indexOf("delete") - 1);
                    }
                    CaravanPurchaseDataItem caravanPurchaseDataItem = purchaseDataMapper.getPurchaseDataItemByPurchaseIdAndSku(purchaseId, sku);
                    if (caravanPurchaseDataItem == null) {
                        FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 1);
                        FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    } else {
                        FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                        FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140206, 2);
                        FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 220211, 1);
                        //获得之前所有的关于这个采购单的出入库流水的库存数量总和
                        Integer quantitySum = storageLogDataMapper.getQuantitySumByDocumentTypeSkuWarehouseDocumentNumTime(documentName, sku, warehouse, documentNum, timeCreate);
                        if (caravanPurchaseDataItem != null && quantitySum > caravanPurchaseDataItem.getPurchaseNum()) {
                            FinanceCaravanDebitCreditRelation debitCreditRelation6 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140206, 1);
                            //将计算后的正确sku数量放入
                            debitCreditRelation6.setSkuNum(quantitySum - caravanPurchaseDataItem.getPurchaseNum());
                            FinanceCaravanDebitCreditRelation debitCreditRelation7 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 220211, 2);
                            //同上
                            debitCreditRelation7.setSkuNum(quantitySum - caravanPurchaseDataItem.getPurchaseNum());
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation6);
                            financeCaravanDebitCreditRelationList.add(debitCreditRelation7);
                        }
                        FinanceCaravanDebitCreditRelation debitCreditRelation4 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 220212, 2);
                        FinanceCaravanDebitCreditRelation debitCreditRelation5 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 112301, 2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation4);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation5);
                    }
                    log.info("采购入库借贷关系生成成功");
                    break;
                case 15://采购单退货出库
                    FinanceCaravanDebitCreditRelation debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140206, 1);
                    FinanceCaravanDebitCreditRelation debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                    FinanceCaravanDebitCreditRelation debitCreditRelation3 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 220211, 1);
                    FinanceCaravanDebitCreditRelation debitCreditRelation4 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 220212, 2);
                    FinanceCaravanDebitCreditRelation debitCreditRelation5 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 112301, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation4);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation5);
                    log.info("采购单退货出库借贷关系生成成功");
                    break;
                case 6://加工原材料出库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1403, 1);
                    //将负数的数量改为正数
                    debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                    //将负数的数量改为正数
                    debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("加工原材料出库借贷关系生成成功");
                    break;
                case 7://加工商品入库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1403, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("加工商品入库借贷关系生成成功");
                    break;
                case 4://分仓调拨入库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140202, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("分仓调拨入库借贷关系生成成功");
                    break;
                case 5://分仓调拨出库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140202, 1);
                    //将负数的数量改为正数
                    debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                    //将负数的数量改为正数
                    debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("分仓调拨出库借贷关系生成成功");
                    break;
                case 3://分仓调拨作废入库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 140202, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("分仓调拨作废入库借贷关系生成成功");
                    break;
                case 13://退货单验货入库
                    //先根据sku、关联的订单号和时间去借贷关系表中查是否有对应的借贷关系数据，有，就直接根据这个借贷关系生成科目就行；
                    // 没有就生成 借：库存商品（金额为仓库近期的单价*数量）   贷：主营业务成本-历史退货
                    List<FinanceCaravanDebitCreditRelation> orderIssueDebitCreditRelationList = financeCaravanDebitCreditRelationMapper.getDataByDocumentTypeSkuWarehouseRelatedRecordNoTime(12, sku, warehouse, documentNum, timeCreate);
                    if (orderIssueDebitCreditRelationList == null || orderIssueDebitCreditRelationList.size() == 0) {
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 640106, 2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    } else {
                        //这里的科目金额就在这边直接计算完了
                        for (int i = 0; i < orderIssueDebitCreditRelationList.size(); i++) {
                            FinanceCaravanDebitCreditRelation debitCreditRelation = orderIssueDebitCreditRelationList.get(i);
                            Integer subjectId = debitCreditRelation.getSubjectId();
                            Integer quantity = storageLogData.getQuantity();
                            if (subjectId == 640105) {
                                debitCreditRelation.setSkuNum(quantity);
                                debitCreditRelation.setAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                debitCreditRelation.setOriginalAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                financeCaravanDebitCreditRelationList.add(debitCreditRelation);
                            }
                            if (subjectId == 1406) {
                                debitCreditRelation.setSkuNum(quantity);
                                debitCreditRelation.setAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                debitCreditRelation.setOriginalAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                financeCaravanDebitCreditRelationList.add(debitCreditRelation);
                            }
                            if (subjectId == 630110) {
                                debitCreditRelation.setSkuNum(quantity);
                                debitCreditRelation.setOriginalAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                debitCreditRelation.setAmount(debitCreditRelation.getAmount().divide(BigDecimal.valueOf(debitCreditRelation.getSkuNum()), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(quantity)));
                                financeCaravanDebitCreditRelationList.add(debitCreditRelation);
                            }
                        }
                    }
                    log.info("退货单验货入库借贷关系生成成功");
                    break;
                case 10://手工出库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 1);
                    //将负数的数量改为正数
                    debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                    //将负数的数量改为正数
                    debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("手工出库借贷关系生成成功");
                    break;
                case 9://手工入库
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 2);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("手工入库借贷关系生成成功");
                    break;
                case 2://修改库存
                    int quantity = storageLogData.getQuantity();
                    if (quantity >= 0) {
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 630108, 2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    } else {
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 1);
                        //将负数的数量改为正数
                        debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 671104, 2);
                        //将负数的数量改为正数
                        debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    }
                    log.info("修改库存借贷关系生成成功");
                    break;
                case 12://订单出库
                    //这里需要去查到关联的订单数据，看订单中到达的店铺名是否和这个sku匹配的店铺名相同
                    CaravanOrderData caravanOrderData = orderDataMapper.getShopNameByPlatformOrderId(documentNum);
                    String targetShopName = caravanOrderData.getShopName();
                    String platformId = caravanOrderData.getPlatformId();
                    FinanceShopSku financeShopSku = shopSkuMapper.getInfoBySku(sku);
                    if (financeShopSku == null) {

                    }
                    String sellerId = financeShopSku.getSellerId();
                    String area = financeShopSku.getArea();
                    //根据马帮定义的店铺名去查找对应的sellerId和area
                    FinanceCaravanShopNameRelation financeCaravanShopNameRelation = financeCaravanShopNameRelationMapper.getInfoByCaravanShopNameAndPlatform(targetShopName, platformId);
                    String targetSellerId = "";
                    String targetArea = "";
                    String shopName = "";
                    if (financeCaravanShopNameRelation != null) {
                        targetSellerId = financeCaravanShopNameRelation.getSelllerId();
                        targetArea = financeCaravanShopNameRelation.getArea();
                        shopName = financeCaravanShopNameRelation.getShopName();
                    }
                    if (sellerId.equals(targetSellerId) && area.equals(targetArea)) {
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 640105, 1);
                        //将负数的数量改为正数
                        debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                        //将负数的数量改为正数
                        debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    } else {
                        //这个借贷关系的店铺信息需要变成目标店铺（targetShopName）的信息
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 640105, 1);
                        debitCreditRelation1.setSellerId(targetSellerId);
                        debitCreditRelation1.setArea(targetArea);
                        debitCreditRelation1.setShopName(shopName);
                        //将负数的数量改为正数
                        debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                        //将负数的数量改为正数
                        debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation3 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 630110, 2);
                        //将负数的数量改为正数
                        debitCreditRelation3.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                    }
                    log.info("订单出库借贷关系生成成功");
                    break;
                case 1://FBA发货出库
                    //这里需要去查到关联的亚马逊发货批次数据，看到达的店铺名是否和这个sku匹配的店铺名相同
                    //从创建计划表wl_create_a_plan获取shipmentId对应的店铺信息
                    WlCreateAPlan wlCreateAPlan = wlCreateAPlanMapper.getShopDataByShipmentId(documentNum);
                    financeShopSku = shopSkuMapper.getInfoBySku(sku);
                    sellerId = "";
                    area = "";
                    if (financeShopSku == null) {
                        errorMsg.append("sku:" + sku + "找不到对应的店铺数据");
                    }
                    if (financeShopSku != null) {
                        sellerId = financeShopSku.getSellerId();
                        area = financeShopSku.getArea();
                    }
                    targetSellerId = "";
                    targetArea = "";
                    targetShopName = "";
                    String positions = "";
                    if (wlCreateAPlan != null) {
                        if (wlCreateAPlan.getShipmentId() == null) {
                            errorMsg.append("找不到对应shipno：" + documentNum + "的发货批次数据");
                        }
                        targetSellerId = wlCreateAPlan.getSellerId();
                        targetArea = wlCreateAPlan.getCountryName();
                        targetShopName = wlCreateAPlan.getShopName();
                        positions = wlCreateAPlan.getPositions();
                    }
                    //这边的subjectId需要去查找一下目的地是哪个仓
                    Integer debitSubjectId = null;
                    if ("美西海外仓".equals(positions)) {
                        debitSubjectId = 140207;
                    } else if ("美东海外仓".equals(positions)) {
                        debitSubjectId = 140208;
                    } else if ("暂估FBA".equals(positions)) {
                        debitSubjectId = 140209;
                    }
                    if (debitSubjectId == null) {
//                        errorMsg.append("，logId:" + storageLogData.getLogId() + ",documentType:" + documentType + "的科目生成出现错误，详情：");
                        errorMsg.append("找不到对应的创建计划，无法确定借方科目");
                        throw new ErrorLogException();
                    }
                    if (sellerId.equals(targetSellerId) && area.equals(targetArea)) {
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, debitSubjectId, 1);
                        //将负数的数量改为正数
                        debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                        //将负数的数量改为正数
                        debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    } else {
                        //这个借贷关系的店铺信息需要变成目标店铺（targetShopName）的信息
                        debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, debitSubjectId, 1);
                        debitCreditRelation1.setSellerId(targetSellerId);
                        debitCreditRelation1.setShopName(targetShopName);
                        debitCreditRelation1.setArea(targetArea);
                        //将负数的数量改为正数
                        debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1406, 2);
                        //将负数的数量改为正数
                        debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        debitCreditRelation3 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 630110, 2);
                        //将负数的数量改为正数
                        debitCreditRelation3.setSkuNum(Math.abs(storageLogData.getQuantity()));
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                        financeCaravanDebitCreditRelationList.add(debitCreditRelation3);
                    }
                    log.info("FBA发货出库借贷关系生成成功");
                    break;
                case 8://库存盘点
                case 11://海外仓出入库
                case 16://excel导入
                    debitCreditRelation1 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 1);
                    //将负数的数量改为正数
                    debitCreditRelation1.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    debitCreditRelation2 = loadStorageLogDataDebitCreditRelation(storageLogData, documentType, 1000, 2);
                    //将负数的数量改为正数
                    debitCreditRelation2.setSkuNum(Math.abs(storageLogData.getQuantity()));
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation1);
                    financeCaravanDebitCreditRelationList.add(debitCreditRelation2);
                    log.info("全手动处理借贷关系生成成功");
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
            errorMsg.append("，logId:" + storageLogData.getLogId() + ",documentType:" + documentType + "的科目生成出现错误，详情：" + e);
            log.warn(errorMsg.toString());
            throw new ErrorLogException(errorMsg.toString());
        }
        return financeCaravanDebitCreditRelationList;
    }

    /**
     * 根据具体单据类型生成借贷关系的值
     */
    private void generateStorageLogDataDebitCreditRelationValue(CaravanStorageLogData storageLogData, List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String documentNum = storageLogData.getDocumentNum();
        String sku = storageLogData.getStockSku();
        Integer quantity = storageLogData.getQuantity();
        String warehouse = storageLogData.getWearhouseName();
        String timeCreate = storageLogData.getTimeCreate();
        String documentName = storageLogData.getDocumentType();
        if ("手工出库".equals(documentName) || "手工入库".equals(documentName)) {
            if (quantity >= 0) {
                documentName = "手工入库";
            } else {
                documentName = "手工出库";
            }
        }
        //先去获取这个sku和仓库的数据是否在这条数据的日期之前有出现过，有就查询下来用他的库存单价和剩余库存做后续计算，没有则去初期库存表中查找
        BigDecimal inventoryUnitPrice;
        BigDecimal remainingInventorySum;
        CaravanStorageLogData previousStorageLogData = storageLogDataMapper.getPreviousDataBySkuAndWarehouse(sku, warehouse, timeCreate);
        if (previousStorageLogData == null) {
            LocalDateTime createTime = LocalDateTime.parse(timeCreate, df);
            String time = LocalDateTime.of(createTime.getYear(), createTime.getMonthValue(), 1, 0, 0, 0).format(df);
            FinanceOpeningInventory financeOpeningInventory = financeOpeningInventoryMapper.getDataBySkuAndWarehouseAndTime(sku, warehouse, time);
            if (financeOpeningInventory == null) {
                inventoryUnitPrice = BigDecimal.ZERO;
                remainingInventorySum = BigDecimal.ZERO;
            } else {
                inventoryUnitPrice = financeOpeningInventory.getInventoryUnitPrice();
                remainingInventorySum = financeOpeningInventory.getRemainingInventorySum();
            }
        } else {
            inventoryUnitPrice = previousStorageLogData.getInventoryUnitPrice();
            remainingInventorySum = previousStorageLogData.getRemainingInventorySum();
        }
        int documentType = financeCaravanDebitCreditRelationList.get(0).getDocumentType();
        try {
            switch (documentType) {
                case 14:  //"采购入库"
                    //如果财务数据中已经有金额值了，表示之前是手动处理导入了，那么只进行剩余库存和库存单价的计算,否则按之前的逻辑计算金额
                    if (financeCaravanDebitCreditRelationList.get(0).getOriginalAmount() == null) {
                        //获得关联采购单对应的信息
                        //如果是采购单，需要把documentNum截取后五位，才是对应的purchaseId
                        String purchaseId = documentNum.substring(documentNum.length() - 5);
                        //先加着，和需求确认好后决定是否删掉
                        if (sku.contains("delete")) {
                            sku = sku.substring(0, sku.indexOf("delete") - 1);
                        }
                        CaravanPurchaseDataItem caravanPurchaseDataItem = purchaseDataMapper.getPurchaseDataItemByPurchaseIdAndSku(purchaseId, sku);
                        BigDecimal sellPrice = caravanPurchaseDataItem.getSellPrice();
                        //计算出各个借贷科目对应的值
                        //库存商品
                        BigDecimal goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(sellPrice);
                        //在途物资-采购
                        BigDecimal materialsInTransitByPurchase1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(sellPrice);
                        // 下面这组借贷关系需要去借贷关系表中找账单类型为付款单，关联单号是对应的采购单号，sku是这个sku，借贷关系是借，科目名是“预付款单-采购”的借贷关系金额，
                        // 以此来确定贷方怎么计算金额
                        BigDecimal amountSum = financeCaravanDebitCreditRelationMapper.getAmountByRecordTypeRelatedRecordSkuLoanTypeSubjectId(2, documentNum, sku, 1, 112301, timeCreate);
                        //应付账款-采购暂估
                        BigDecimal accountspayableByPurchaseEstimation2 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(2).getSkuNum()).multiply(sellPrice);
                        //应付账款-采购
                        BigDecimal accountspayableByPurchase3;
                        //预付账款-采购
                        BigDecimal prepaymentByPurchase4;
                        if (amountSum.compareTo(BigDecimal.ZERO) > 0) {
                            prepaymentByPurchase4 = amountSum;
                            accountspayableByPurchase3 = accountspayableByPurchaseEstimation2.subtract(prepaymentByPurchase4);
                        } else {
                            accountspayableByPurchase3 = accountspayableByPurchaseEstimation2;
                            prepaymentByPurchase4 = BigDecimal.ZERO;
                        }
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), materialsInTransitByPurchase1);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(2), accountspayableByPurchaseEstimation2);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(3), accountspayableByPurchase3);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(4), prepaymentByPurchase4);
                        //这里需要去查到具体账单种类、关联的采购单号和sku一样的之前的出入库数据，把数量都加起来看看是不是实际入库的比采购单的多，如果是，则再加一组借贷关系
                        Integer quantitySum = storageLogDataMapper.getQuantitySumByDocumentTypeSkuWarehouseDocumentNumTime(documentName, sku, warehouse, documentNum, timeCreate);
                        if (caravanPurchaseDataItem != null && quantitySum > caravanPurchaseDataItem.getPurchaseNum()) {
                            //在途物资-采购
                            BigDecimal materialsInTransitByPurchase5 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(5).getSkuNum()).multiply(sellPrice);
                            //应付账款-采购暂估
                            BigDecimal accountspayableByPurchaseEstimation6 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(6).getSkuNum()).multiply(sellPrice);
                            loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(5), materialsInTransitByPurchase5);
                            loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(6), accountspayableByPurchaseEstimation6);
                        }
                        //计算出当前这条数据的剩余库存和库存单价
                        remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(sellPrice));
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    } else {
                        //将页面已经处理过后的财务数据中的借方或贷方的金额相加，之前的剩余库存加上这个金额就是当前的剩余库存
                        BigDecimal financeAmount = BigDecimal.ZERO;
                        for (FinanceCaravanDebitCreditRelation debitCreditRelation : financeCaravanDebitCreditRelationList) {
                            if (debitCreditRelation.getLoanType() == 1) {
                                BigDecimal originalAmount = debitCreditRelation.getOriginalAmount();
                                financeAmount = financeAmount.add(originalAmount);
                            }
                        }
                        remainingInventorySum = remainingInventorySum.add(financeAmount);
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("采购入库借贷关系金额生成成功");
                    break;
                case 15://采购单退货出库,这个借贷的数据需要反冲，所以要加上符号计算
                    //获得关联采购单对应的信息
                    //如果是采购单，需要把documentNum截取后五位，才是对应的purchaseId
                    String purchaseId = documentNum.substring(documentNum.length() - 5);
                    CaravanPurchaseDataItem caravanPurchaseDataItem = purchaseDataMapper.getPurchaseDataItemByPurchaseIdAndSku(purchaseId, sku);
                    BigDecimal sellPrice = caravanPurchaseDataItem.getSellPrice();
                    //在途物资-采购
                    BigDecimal materialsInTransitByPurchase0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(sellPrice);
                    //库存商品
                    BigDecimal goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(sellPrice);
                    // 下面这组借贷关系需要去借贷关系表中找账单类型为收款单，关联单号是对应的采购单号，sku是这个sku，借贷关系是借，科目名是“预付款单-采购”的借贷关系金额，
                    // 以此来确定贷方怎么计算金额
                    BigDecimal amountSum = financeCaravanDebitCreditRelationMapper.getAmountByRecordTypeRelatedRecordSkuLoanTypeSubjectId(1, documentNum, sku, 1, 112301, timeCreate);
                    //应付账款-采购暂估
                    BigDecimal accountspayableByPurchaseEstimation2 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(2).getSkuNum()).multiply(sellPrice);
                    //应付账款-采购
                    BigDecimal accountspayableByPurchase3;
                    //预付账款-采购
                    BigDecimal prepaymentByPurchase4;
                    if (amountSum.compareTo(BigDecimal.ZERO) > 0) {
                        //预付账款-采购
                        prepaymentByPurchase4 = BigDecimal.ZERO.subtract(amountSum);
                        //应付账款-采购
                        accountspayableByPurchase3 = accountspayableByPurchaseEstimation2.subtract(prepaymentByPurchase4);
                    } else {
                        accountspayableByPurchase3 = accountspayableByPurchaseEstimation2;
                        prepaymentByPurchase4 = BigDecimal.ZERO;
                    }
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), materialsInTransitByPurchase0);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(2), accountspayableByPurchaseEstimation2);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(3), accountspayableByPurchase3);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(4), prepaymentByPurchase4);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(sellPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("采购单退货出库借贷关系金额生成成功");
                    break;
                case 6://加工原材料出库
                    //库存商品
                    BigDecimal goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                    //原材料
                    BigDecimal rawMaterial1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), rawMaterial1);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("加工原材料出库借贷关系金额生成成功");
                    break;
                case 7://加工商品入库
                    //需要通过加工单数据去求得加工后商品的价格
                    List<FinanceCaravanProcessingOrderItem> processingOrderItemList = caravanProcessingOrderItemMapper.getDataByProcessingDocumentNoWarehouseToSku(documentNum, warehouse, sku);
                    BigDecimal amount = BigDecimal.ZERO;
                    for (FinanceCaravanProcessingOrderItem processingOrderItem : processingOrderItemList) {
                        String fromSku = processingOrderItem.getFromSku();
                        Integer fromSkuNum = processingOrderItem.getFromSkuNum();
                        CaravanStorageLogData fromSkuStorageLogData = storageLogDataMapper.getDataByDocumentTypeSkuWarehouseDocumentNumTime("加工原材料出库", fromSku, documentNum, timeCreate);
                        amount = amount.add(BigDecimal.valueOf(fromSkuNum).multiply(fromSkuStorageLogData.getInventoryUnitPrice()));
                    }
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), amount);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), amount);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(amount);
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("加工商品入库借贷关系金额生成成功");
                    break;
                case 4://分仓调拨入库
                    //在途物资-调拨在途
                    BigDecimal inTransitMaterialsByTransferInTransit0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                    //库存商品
                    goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), inTransitMaterialsByTransferInTransit0);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("分仓调拨入库借贷关系金额生成成功");
                    break;
                case 5://分仓调拨出库
                    //库存商品
                    goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                    //在途物资-调拨在途
                    BigDecimal inTransitMaterialsByTransferInTransit1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), inTransitMaterialsByTransferInTransit1);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("分仓调拨出库借贷关系金额生成成功");
                    break;
                case 3://分仓调拨作废入库
                    //库存商品
                    goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                    //在途物资-调拨在途
                    inTransitMaterialsByTransferInTransit1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                    loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), inTransitMaterialsByTransferInTransit1);
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("分仓调拨作废入库借贷关系金额生成成功");
                    break;
                case 13://退货单验货入库
                    //需要去查找到有一样关联批次号且离自身数据时间最近的那条数据，有就用这条数据的库存单价；没有就用自己当前的
                    //List<FinanceCaravanDebitCreditRelation> orderIssueDebitCreditRelationList = financeCaravanDebitCreditRelationMapper.getDataByDocumentTypeSkuWarehouseRelatedRecordNoTime(documentType, sku, warehouse, documentNum, timeCreate);
                    if (financeCaravanDebitCreditRelationList.get(0).getOriginalAmount() == null) {
                        //库存商品
                        goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //主营业务成本-历史退货
                        BigDecimal mainBusinessCostByHistoricalReturn1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), mainBusinessCostByHistoricalReturn1);
                    }
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.subtract(financeCaravanDebitCreditRelationList.get(0).getOriginalAmount());
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("退货单验货入库借贷关系金额生成成功");
                    break;
                case 10://手工出库
                    //如果新增后的财务数据没有金额，直接根据现有的库存单价给他计算出来,如果有了金额，那么就根据有的财务数据反推剩余库存金额和单价
                    if (financeCaravanDebitCreditRelationList.get(0).getOriginalAmount() == null) {
                        //手动确认
                        BigDecimal manualConfirmation0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //库存商品
                        goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), manualConfirmation0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                        //计算出当前这条数据的剩余库存和库存单价
                        remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        } else {
                            inventoryUnitPrice = BigDecimal.ZERO;
                        }
                    } else {
                        BigDecimal financeAmount = BigDecimal.ZERO;
                        for (FinanceCaravanDebitCreditRelation debitCreditRelation : financeCaravanDebitCreditRelationList) {
                            if (debitCreditRelation.getLoanType() == 1) {
                                BigDecimal originalAmount = debitCreditRelation.getOriginalAmount();
                                financeAmount = financeAmount.add(originalAmount);
                            }
                        }
                        remainingInventorySum = remainingInventorySum.add(financeAmount);
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("手工出库借贷关系金额生成成功");
                    break;
                case 9://手工入库
                    //如果新增后的财务数据没有金额，直接根据现有的库存单价给他计算出来,如果有了金额，那么就根据有的财务数据反推剩余库存金额和单价
                    if (financeCaravanDebitCreditRelationList.get(1).getOriginalAmount() == null) {
                        //库存商品
                        goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //手动确认
                        BigDecimal manualConfirmation1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), manualConfirmation1);
                        //计算出当前这条数据的剩余库存和库存单价
                        remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        } else {
                            inventoryUnitPrice = BigDecimal.ZERO;
                        }
                    } else {
                        //库存商品
                        goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        BigDecimal financeAmount = BigDecimal.ZERO;
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        for (FinanceCaravanDebitCreditRelation debitCreditRelation : financeCaravanDebitCreditRelationList) {
                            if (debitCreditRelation.getLoanType() == 1) {
                                BigDecimal originalAmount = BigDecimal.ZERO;
                                if (debitCreditRelation.getOriginalAmount() != null) {
                                    originalAmount = debitCreditRelation.getOriginalAmount();
                                }
                                financeAmount = financeAmount.add(originalAmount);
                            }
                        }
                        remainingInventorySum = remainingInventorySum.add(financeAmount);
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("手工入库借贷关系金额生成成功");
                    break;
                case 2://修改库存
                    if (quantity >= 0) {
                        //库存商品
                        goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //营业外收入-盘盈
                        BigDecimal nonbusinessIncomeByInventoryProfit1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), nonbusinessIncomeByInventoryProfit1);
                    } else {
                        //库存商品
                        goodsInStock0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //营业外收入-盘亏
                        BigDecimal nonbusinessIncomeByInventoryLoss1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), goodsInStock0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), nonbusinessIncomeByInventoryLoss1);
                    }
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    } else {
                        inventoryUnitPrice = BigDecimal.ZERO;
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("修改库存借贷关系金额生成成功");
                    break;
                case 12://订单出库
                    //这里需要去查到关联的订单数据，看订单中到达的店铺名是否和这个sku匹配的店铺名相同
                    CaravanOrderData caravanOrderData = orderDataMapper.getShopNameByPlatformOrderId(documentNum);
                    String targetShopName = caravanOrderData.getShopName();
                    String platformId = caravanOrderData.getPlatformId();
                    FinanceShopSku financeShopSku = shopSkuMapper.getInfoBySku(sku);
                    String sellerId = financeShopSku.getSellerId();
                    String area = financeShopSku.getArea();
                    FinanceCaravanShopNameRelation financeCaravanShopNameRelation = financeCaravanShopNameRelationMapper.getInfoByCaravanShopNameAndPlatform(targetShopName, platformId);
                    String targetSellerId = "";
                    String targetArea = "";
//                String shopName = "";
                    if (financeCaravanShopNameRelation != null) {
                        targetSellerId = financeCaravanShopNameRelation.getSelllerId();
                        targetArea = financeCaravanShopNameRelation.getArea();
//                    shopName = financeCaravanShopNameRelation.getShopName();
                    }
                    if (sellerId.equals(targetSellerId) && area.equals(targetArea)) {
                        //主营业务成本-自配送
                        BigDecimal mainBusinessCostBySelfDelivery0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //库存商品
                        goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), mainBusinessCostBySelfDelivery0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                    } else {
                        //库存商品
                        goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        //代购利润
                        BigDecimal agentPurchaseProfit2 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(BigDecimal.ONE);
                        //主营业务成本-自配送
                        BigDecimal mainBusinessCostBySelfDelivery0 = goodsInStock1.add(agentPurchaseProfit2);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), mainBusinessCostBySelfDelivery0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(2), agentPurchaseProfit2);
                    }
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("订单出库借贷关系金额生成成功");
                    break;
                case 1://FBA发货出库
                    //这里需要去查到关联的亚马逊发货批次数据，看到达的店铺名是否和这个sku匹配的店铺名相同
                    WlCreateAPlan wlCreateAPlan = wlCreateAPlanMapper.getShopDataByShipmentId(documentNum);
                    financeShopSku = shopSkuMapper.getInfoBySku(sku);
                    sellerId = financeShopSku.getSellerId();
                    area = financeShopSku.getArea();
                    targetSellerId = "";
                    targetArea = "";
                    if (wlCreateAPlan != null) {
                        targetSellerId = wlCreateAPlan.getSellerId();
                        targetArea = wlCreateAPlan.getCountryName();
                    }
                    if (sellerId.equals(targetSellerId) && area.equals(targetArea)) {
                        //在途物资-（子科目名，已经在生成科目名时确定）
                        BigDecimal materialsInTransit0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //库存商品
                        goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), materialsInTransit0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                    } else {
                        //库存商品
                        goodsInStock1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        //代购利润
                        BigDecimal agentPurchaseProfit2 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(BigDecimal.ONE);
                        //在途物资-（子科目名，已经在生成科目名时确定）
                        BigDecimal materialsInTransit0 = goodsInStock1.add(agentPurchaseProfit2);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), materialsInTransit0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), goodsInStock1);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(2), agentPurchaseProfit2);
                    }
                    //计算出当前这条数据的剩余库存和库存单价
                    remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                    if (storageLogData.getQuantityAfter() != 0) {
                        inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("FBA发货出库借贷关系金额生成成功");
                    break;
                case 8://库存盘点
                case 11://海外仓出入库
                case 16://excel导入
                    //如果是这些类型，能进入这个方法就说明是已经将手动处理的科目给处理了，这边只需要把当前出入库流水的剩余库存和库存单价计算出来就可以了
                    log.info("以处理过手动处理的财务数据，生成该出入库流水记录的剩余库存和库存单价");
                    //如果新增后的财务数据没有金额，直接根据现有的库存单价给他计算出来,如果有了金额，那么就根据有的财务数据反推剩余库存金额和单价
                    if (financeCaravanDebitCreditRelationList.get(0).getOriginalAmount() == null) {
                        //手动确认
                        BigDecimal manualConfirmation0 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(0).getSkuNum()).multiply(inventoryUnitPrice);
                        //手动确认
                        BigDecimal manualConfirmation1 = BigDecimal.valueOf(financeCaravanDebitCreditRelationList.get(1).getSkuNum()).multiply(inventoryUnitPrice);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(0), manualConfirmation0);
                        loadStorageLogDataDebitCreditRelationValue(financeCaravanDebitCreditRelationList.get(1), manualConfirmation1);
                        //计算出当前这条数据的剩余库存和库存单价
                        remainingInventorySum = remainingInventorySum.add(BigDecimal.valueOf(quantity).multiply(inventoryUnitPrice));
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    } else {
                        //将页面已经处理过后的财务数据中的借方或贷方的金额相加，之前的剩余库存加上这个金额就是当前的剩余库存
                        BigDecimal financeAmount = BigDecimal.ZERO;
                        for (FinanceCaravanDebitCreditRelation debitCreditRelation : financeCaravanDebitCreditRelationList) {
                            if (debitCreditRelation.getLoanType() == 1) {
                                BigDecimal originalAmount = debitCreditRelation.getOriginalAmount();
                                financeAmount = financeAmount.add(originalAmount);
                            }
                        }
                        remainingInventorySum = remainingInventorySum.add(financeAmount);
                        if (storageLogData.getQuantityAfter() != 0) {
                            inventoryUnitPrice = remainingInventorySum.divide(BigDecimal.valueOf(storageLogData.getQuantityAfter()), 4, BigDecimal.ROUND_HALF_UP);
                        }
                    }
//                    storageLogData.setHandleStatus(2);
                    storageLogData.setRemainingInventorySum(remainingInventorySum);
                    storageLogData.setInventoryUnitPrice(inventoryUnitPrice);
                    log.info("生成该出入库流水记录的剩余库存和库存单价成功");
                    break;
            }
        } catch (Exception e) {
            log.warn("logId:" + storageLogData.getLogId() + ",documentType:" + documentType + "的科目金额生成出现错误，详情：" + e);
            throw new ErrorLogException("logId:" + storageLogData.getLogId() + ",documentType:" + documentType + "的科目金额生成出现错误，详情：" + e);
        }
    }

    /**
     * 通用的生成出入库流水的借贷关系的方法
     */
    private FinanceCaravanDebitCreditRelation loadStorageLogDataDebitCreditRelation(CaravanStorageLogData storageLogData, int documentType, int subjectId, int loanType) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowTime = LocalDateTime.now().format(df);
        String sku = storageLogData.getStockSku();
        FinanceCaravanDebitCreditRelation debitCreditRelation = new FinanceCaravanDebitCreditRelation();
        debitCreditRelation.setRecordNo(storageLogData.getLogId());
        debitCreditRelation.setRecordType(5);
        //获得当前这条数据的sku对应的店铺信息
        FinanceShopSku financeShopSku = shopSkuMapper.getInfoBySku(sku);
        if (financeShopSku != null) {
            debitCreditRelation.setSellerId(financeShopSku.getSellerId());
            debitCreditRelation.setShopName(financeShopSku.getShopName());
            debitCreditRelation.setArea(financeShopSku.getArea());
        } else {
            debitCreditRelation.setSellerId("");
            debitCreditRelation.setShopName("");
            debitCreditRelation.setArea("");
        }
        debitCreditRelation.setSku(sku);
        debitCreditRelation.setSkuNum(storageLogData.getQuantity());
        debitCreditRelation.setWarehouse(storageLogData.getWearhouseName());
        debitCreditRelation.setRelatedRecordNo(storageLogData.getDocumentNum());
        debitCreditRelation.setDocumentType(documentType);
        debitCreditRelation.setLoanType(loanType);
        //这里需要根据subjectID查找到子父科目名
        FinanceSubject financeSubject = subjectMapper.getInfoBysubjectId(subjectId);
        debitCreditRelation.setSubjectId(subjectId);
        debitCreditRelation.setPSubjectName(financeSubject.getPSubject());
        debitCreditRelation.setCSubjectName(financeSubject.getSubject());
        debitCreditRelation.setCurrency("CNY");
        debitCreditRelation.setDataTime(storageLogData.getTimeCreate());
        debitCreditRelation.setRelatedPerson(storageLogData.getOperName());
        debitCreditRelation.setCreator("系统生成");
        debitCreditRelation.setCreateTime(nowTime);
        debitCreditRelation.setStatus(1);
        debitCreditRelation.setIsInventoryDetails(1);
        return debitCreditRelation;
    }

    /**
     * 通用的生成出入库流水的借贷关系值的方法
     */
    private FinanceCaravanDebitCreditRelation loadStorageLogDataDebitCreditRelationValue(FinanceCaravanDebitCreditRelation debitCreditRelation, BigDecimal amount) {
        debitCreditRelation.setAmount(amount);
        debitCreditRelation.setOriginalAmount(amount);
        return debitCreditRelation;
    }

    public void dataTest() {
        log.info("-------------------------------开始采购单的财务数据----------------------------------");
        List<CaravanPurchaseData> purchaseDataList = purchaseDataMapper.getPurchasingAndNewDataInTwoMonth();
        for (CaravanPurchaseData purchaseData : purchaseDataList) {
            //创建存放借贷关系数据的集合
            String purchaseId = purchaseData.getPurchaseId();
            //获得对应的采购单明细
            List<CaravanPurchaseDataItem> purchaseDataItemList = purchaseDataMapper.getNewItemDataByPurchaseId(purchaseId);
            List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = generatePurchaseDataDebitCreditRelation(purchaseData, purchaseDataItemList);
            //更新采购单处理状态
            purchaseDataMapper.updateHandleStatus(purchaseData);
            //插入或更新借贷关系
            if (financeCaravanDebitCreditRelationList.size() != 0) {
                financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
            }
        }

        log.info("-------------------------------开始出入库流水的财务数据----------------------------------");
        List<CaravanStorageLogData> storageLogDataList = storageLogDataMapper.selectNewAndHandledDataInTwoMonth();
        int flag = 1;
        for (CaravanStorageLogData storageLogData : storageLogDataList) {
            flag = calculateStorageLogDataWithTransaction(storageLogData, flag);
        }

        log.info("-------------------------------开始账单的财务数据----------------------------------");
        List<CaravanBillsData> billsDataList = billsDataMapper.getCompletedAndNewDataInTwoMonth();
        for (CaravanBillsData billsData : billsDataList) {
            //生成借贷关系
            List<FinanceCaravanDebitCreditRelation> financeCaravanDebitCreditRelationList = generateBillsDataDebitCreditRelation(billsData);
            //更新账单的处理状态
            billsDataMapper.updateHandleStatus(billsData);
            //插入或更新借贷关系
            financeCaravanDebitCreditRelationMapper.insertList(financeCaravanDebitCreditRelationList);
        }
    }


    /**
     * 将api出错信息插入数据库
     *
     * @param date
     * @param errorMsg
     */
    private void handleErrorSchedule(String date, String name, StringBuffer errorMsg) {
        DataGetErrorRecordDO record = new DataGetErrorRecordDO();
        record.setSellerId("");
        record.setArea("");
        record.setDate(date);
        //是否处理，0:未处理,1:已处理',
        record.setIsHandle(0);
        //类型:亚马逊财务数据计算
        record.setType(3);
        record.setName(name);
        record.setRemark(errorMsg.toString());
        iDataGetErrorRecordMapper.insert(record);
    }
}
